/**
 * Copyright (C) 2012  The CFuture Android Ad-platform Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lurencun.android.support.ad;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;

import com.lurencun.android.support.ad.i.AdTipDialog;
import com.lurencun.android.support.ad.i.OnDialogListener;

/**
 * 广告平台的统一抽象接口。<br/>
 * 这里使用的是广告积分墙的广告方式，不支持Banner类广告。
 * @author cfuture.chenyoca [桥下一粒砂] (chenyoca@163.com)
 * @date 2012-2-14
 */
public abstract class AdSense {

	/**
	 * 当网络没有激活时，广告控件会不断的尝试连接网络，读取余额信息
	 * 这里设置连接网络的时间间隔，单位毫秒。
	 */
	private static final long UPDATE_BALANCE_INTERVAL = 3000L;
	
	private final static String BALANCE_TIP = "您当前拥有 %d %s (含系统赠送).";
	
	protected Context mContext;
	
	/**
	 * 支付回调接口
	 * 当支付动作被执行后，调用此接口的方法处理支付结果回调
	 */
	protected OnPayedListener mPayListener;
	
	/**
	 * 用于自动更新用户余额的定时器
	 */
	private Timer mUpdateTimer;
	
	/**
	 * 显示提示信息的弹出窗口
	 */
	private AdTipDialog mDialog;
	
	/**
	 * 用户余额
	 */
	private Float mBalance;
	
	/**
	 * 是否可以显示广告的标识
	 *  * 当使用时间开关时使用
	 */
	private boolean mShowAd = true;
	
	/**
	 * 默认的解锁少量数据的支付额度
	 */
	private int mDefaultBitAmount = 18;
	
	/**
	 * 默认的解锁大量数据的支付额度
	 */
	private int mDefaultMassAmount = 50;

	private String mAmountName = "金币";
	/**
	 * 解锁提示信息
	 */
	private String mDefaultMessage = "数据已经被锁定，请问您需要解锁吗？";
	
	/**
	 * 弹出窗口的按钮回调。
	 * <br/>
	 * 弹出窗口有三个按钮，分别处理三个点击事件
	 */
	private OnDialogListener mListener = new OnDialogListener() {
		
		@Override
		public void onUnlocMassData() {
			doConsume(mDefaultMassAmount);
			mDialog.cancel();
		}
		@Override
		public void onUnlocBitData() {
			doConsume(mDefaultBitAmount);
			mDialog.cancel();
		}
		@Override
		public void onShowOfferWall() {
			showOfferWall();
			mDialog.cancel();
		}
	};
	
	/**
	 * 构建广告基类，需要传入支付回调接口。
	 * 当用户支付动作发生后，通过此接口进行回调处理。
	 * @param context 环境上下文对象引用
	 * @param listener 支付回调接口。当用户支付动作发生后，通过此接口进行回调处理。
	 */
	public AdSense(Context context,OnPayedListener listener) {
		mContext = context;
		mPayListener = listener;
		mDialog = new AdTipDialog(mContext, mListener);
	}
	
	/**
	 * 启动定时用户余额更新。
	 * 执行此方法将启动一个定时任务，定时间隔由UPDATE_BALANCE_INTERVAL设定。
	 * 当获取余额成功后，定时任务会被取消。
	 */
	protected void startUpdate(){
		mUpdateTimer = new Timer(true);
		mUpdateTimer.schedule(new TimerTask() {
			@Override
			public void run() {
				float balance = updateBalances();
				if(balance >= 0.0f){
					mBalance = balance;
					mUpdateTimer.cancel();
				}
			}
		},0,UPDATE_BALANCE_INTERVAL);
	}

	/**
	 * 开启时间限制。
	 * 调用此方法后，在系统时间没有到达endTime之前，将不会显示广告。
	 * @param endTime 限制结束时间格式:yyyy-MM-dd HH:mm:ss
	 */
	public final void openTimeLimit(String endTime) {
		try {
			SimpleDateFormat dfs = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			Date begin = dfs.parse(endTime);
			long min = (new Date().getTime() - begin.getTime()) / 60000;
			mShowAd =  min >= 0;
		} catch (Exception e) {
			mShowAd = true;
		}
	}

	/**
	 * 判断是否可以显示广告
	 * @return 可以显示则返回true。 
	 */
	public final boolean canShowAd() {
		return mShowAd;
	}

	/**
	 * 显示广告弹出窗口
	 */
	public final void showDialog() {
		StringBuffer message = new StringBuffer(String.format(BALANCE_TIP, (int)getBalances(),mAmountName));
		message.append("\n").append(mDefaultMessage);
		mDialog.setMessage(message.toString());
		mDialog.show();
	}

	/**
	 * 支付实现，由具体广告平台实现
	 * @param payGold 支付的金额
	 */
	protected abstract void doConsume(int payGold);

	/**
	 * 显示积分墙
	 */
	public abstract void showOfferWall();

	/**
	 * 取得用户余额。
	 * @return 用户余额数
	 */
	protected final float getBalances(){
		synchronized(mBalance){
			return mBalance;
		}
	}

	/**
	 * 设置解锁少量数据需要支付的金额
	 * @param amount 金额
	 */
	public void setBitAmount(int amount) {
		this.mDefaultBitAmount = amount;
	}

	/**
	 * 设置解锁大量数据需要支付的金额
	 * @param amount 金额
	 */
	public void setMassAmount(int amount) {
		this.mDefaultMassAmount = amount;
	}
	
	/**
	 * 设置金额名称，如果金币，积分，M币等。
	 * @param name 名称
	 */
	public void setAmountName(String name) {
		this.mAmountName = name;
	}
	
	/**
	 * 设置提示信息。
	 * 这信息将显示在弹出窗口中。
	 * @param message 提示信息
	 */
	public void setMessage(String message){
		this.mDefaultMessage = message;
	}
	
	/**
	 * 销毁广告线程
	 */
	protected void destroy(){}

	/**
	 * 由具体广告平台实现，连接网络更新用户余额。
	 * @return 如果连接网络读取用户余额数据成功，返回大于等于 0.0f 的值，
	 * 			如果需要继续查询网络数据，返回小于0.0f 的值。
	 */
	protected abstract float updateBalances();

}
